﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GTA;

namespace GTAHookAdv.Overlay
{
    public class LabelOverlay : ControlOverlay<System.Windows.Forms.Label>
    {
        GTA.Font _font;

        public LabelOverlay(Script owner)
            : base(owner)
        {
            this.AutoSize = true;
            _font = new Font();
            Ctrl.Font = _font.WindowsFont;
            _textFinal = Ctrl.Text;
            SizeChanged += CalculateFinalText;
            TextChanged += CalculateFinalText;
            MaximumSizeChanged += CalculateFinalText;
            FontChanged += CalculateFinalText;
            WarpChanged += CalculateFinalText;
            ForeColorChanged += FontColorApply;
            FontChanged += FontColorApply;
            
        }

        

        private void CalculateFinalText(object sender, EventArgs e)
        {
            if (!Warp)
            {
                _textFinal = Text;
                return;
            }
            else
            {
                System.Drawing.Size size;
                if (AutoSize)
                    size = MaximumSize;
                else
                    size = Size;
                _textFinal = TextHelper.WarpText(Text, size.Width,FontGTA);
            }
            if (AutoSize)
            {
                System.Drawing.Size textSize = TextHelper.MesureTextSize(_textFinal, FontGTA);
                //I don't call this.Size as AutoSize is true
                Ctrl.Size = new System.Drawing.Size(
                    (textSize.Width > MaximumSize.Width) ? MaximumSize.Width : textSize.Width,
                    (textSize.Height > MaximumSize.Height) ? MaximumSize.Height : textSize.Height);
            }
        }

        private bool _textWithTransparency = true;

        /// <summary>
        /// true by default.
        /// if False <see cref="Opacity"/> will not be applyed to text
        /// </summary>
        public bool TextWithTransparency
        {
            get { return _textWithTransparency; }
            set { _textWithTransparency = value; }
        }


        protected override void Draw()
        {
            DrawOptions options;
            if (TextWithTransparency)
                options = DrawOptions.None;
            else
                options = DrawOptions.IgnoreOpacity;

            DrawText(_textFinal, new System.Drawing.RectangleF(PointToScreen(this.Location), this.Size), TextAlignment, FontGTA, options);
        }

        private bool _warp;

        public bool Warp
        {
            get { return _warp; }
            set {
                bool old = _warp;
                _warp = value;
                if (old != _warp && WarpChanged != null)
                    WarpChanged(this, EventArgs.Empty);
            }
        }

        /// <summary>
        /// This uses <see cref="System.Windows.Forms.Control.Size"/> BUT this field is special with <see cref="LabelOverlay"/>
        /// You can set it only if <see cref="AutoSize"/> is false.Look at the docs for very important details.
        /// You should also have a look on <see cref="System.Windows.Forms.Control.Size"/> docs as we use it, so you also have to respect its rules to avoid exceptions.
        /// </summary>
        /// <remarks>This field is different from others <see cref="ControlOverlay{T}"/> objects. If <see cref="AutoSize"/> is true, you cannot change its value as it is dynamics.
        /// When <see cref="AutoSize"/> is true, Size depends on <see cref="Warp"/> value, <see cref="FontGTA"/>, and <see cref="Text"/> fields values. In this case, you have to use <see cref="MinimumSize"/> and <see cref="MaximumSize"/>.
        /// 
        /// When <see cref="AutoSize"/> is false, then Size haves the same behaviour than other <see cref="ControlOverlay{T}"/> classes, you can set a value to define the fixed control size on screen (based on a 1920x1080 resolution).
        /// 
        /// Remember that all Locations Sizes fields are based on a 1920x1080 Resolution, you don't have to worry if player will have an other Resolution, it will be automaticly scaled.</remarks>
        /// 
        ///<exception cref="InvalidOperationException">If you try to set a value when <see cref="AutoSize"/> is set to true</exception>
        ///<seealso cref="Warp"/>
        ///<seealso cref="AutoSize"/>
        ///<seealso cref="MinimumSize"/>
        ///<seealso cref="MaximumSize"/>
        ///<seealso cref="System.Windows.Forms.Control.Size"/>
        public override System.Drawing.Size Size
        {
            get
            {
                return base.Size;
            }
            set
            {
                if (AutoSize)
                    throw new InvalidOperationException("When AutoSide is set, Size becomes dynamic. Use MinimumSize and MaximumSize or set AutoSize to False");
                base.Size = value;
            }
        }
        
        public event EventHandler WarpChanged;

        private String _textFinal;

        public GTA.Font FontGTA
        {
            get { return _font; }
            set
            {
                if (value == null)
                    throw new ArgumentNullException();
                
                if (_font != null)
                    _font.Dispose();
                _font = value;
                Ctrl.Font = _font.WindowsFont;
            }
        }

        private void FontColorApply(object sender, EventArgs e)
        {
            _font.Color = ForeColor;
        }

        /// <summary>
        /// This method makes your life easier. Just give some basic option to setup this Control Font.
        /// no return, result will be affected to <see cref="FontGTA"/> field.
        /// </summary>
        /// <param name="pixelHeigh">guess :)</param>
        /// <param name="bold">guess :)</param>
        /// <param name="italic">guess :)</param>
        /// <param name="effect"> edges (borders) or shadow can be drawn around chars</param>
        /// <param name="EdgeColor">optional : color of the edges (BackGroundColor by default). Only the first color will be used.</param>
        public void FontFactory(int pixelHeigh,bool bold,bool italic,FontEffect effect,params System.Drawing.Color[] EdgeColor)
        {
            System.Drawing.Color color;
            if (EdgeColor.Length > 0)
                color = EdgeColor[0];
            else
                color = BackColor;
            this.FontGTA = TextHelper.FontFactory(pixelHeigh, bold, italic, effect, color);
        }

      

        #region routed Fields

        public bool AutoSize
        {
            get { return Ctrl.AutoSize; }
            set { Ctrl.AutoSize = value; }
        }

        public event EventHandler FontChanged
        {
            add { Ctrl.FontChanged += value; }
            remove { Ctrl.FontChanged -= value; }
        }

        GTA.TextAlignment _textAlign = TextAlignment.Left;

        public GTA.TextAlignment TextAlignment
        {
            get { return _textAlign; }
            set { _textAlign = value; }
        }

        #endregion

        public override void Dispose()
        {
            if (_font != null)
                _font.Dispose();
            SizeChanged -= CalculateFinalText;
            TextChanged -= CalculateFinalText;
            MaximumSizeChanged -= CalculateFinalText;
            FontChanged -= CalculateFinalText;
            WarpChanged -= CalculateFinalText;
            ForeColorChanged -= FontColorApply;
            FontChanged -= FontColorApply;
            base.Dispose();
        }
    }
}
